<?php

abstract class Dcmp_Component_Controller {

	private $_component = NULL;
	
    public function __construct($component) {
		$this->_component = $component;
		$this->initialize();
    }
    
    protected function initialize(){}

    protected function __($langKey) {
        return Kd_Localize_Helper::__($langKey);
    }

    protected function __f() {
        $args = func_get_args();
        return call_user_func_array(array('Kd_Localize_Helper', '__f'), $args);
    }

    protected function redirect($url) {
        $this->getResponse()->redirect($url);
    }
    
    public function getDomain(){
    	return $this->getComponent()->getDomain();
    }    
    
    protected function getComponent(){
    	return $this->_component;
    }

    protected function getRequest() {
        return Kd_Web::getRequest();
    }

    protected function getResponse() {
        return Kd_Web::getResponse();
    }

    protected function getSession() {
        return Kd_Web::getSession();
    }

    protected function getVariables() {
        return Kd_Web::getVariables();
    }

    protected function getMessager() {
        return Kd_Web::getMessager();
    }

    protected function getHistory() {
        return Kd_Web::getHistory();
    }
    
    protected function getPage(){
        return Kd_Web::getPage();
    }

    protected function getRouter(){
        return Kd_Web::getRouter();
    }

    protected function getIdentity(){
        return Kd_Web::getIdentity();
    }

    protected function getUrl($arguments = array(), $action = '*', $controller = '*', $component = '*') {
        return $this->getRouter()->buildUrl("$component/$controller/$action", $arguments);
    }

    protected function getHistoryUrl($actionPath){
    	$actionPath = $this->getRouter()->buildUrl($actionPath, NULL);
        return $this->getHistory()->get($actionPath);
    }

    protected function viewResult($values = array(), $actionName = NULL, $controllerName = NULL) {
        $result = new Dcmp_Component_Result_View($this->getComponent());
        $result->setActionName($actionName)
               ->setControllerName($controllerName);
        if (!empty($values) && is_array($values)) {
            $result->addData($values);
        }
        return $result;
    }

    protected function redirectResult($url, $inform = NULL, $error = NULL) {
        $result = new Dcmp_Component_Result_Redirect($this->getComponent());
        $result->setUrl($url)
        	   ->setInform($inform)
        	   ->setError($error);
        return $result;
    }
    
    protected function historyResult($actionPath, $inform = NULL, $error = NULL) {
    	$actionPath = $this->getRouter()->buildUrl($actionPath, NULL);
        $result = new Dcmp_Component_Result_History($this->getComponent());
        $result->setActionPath($actionPath)
        	   ->setInform($inform)
        	   ->setError($error);
        return $result;
    }    

    protected function contentResult($content) {
        $result = new Dcmp_Component_Result_Content($this->getComponent());
        $result->setContent($content);
        return $result;
    }

    protected function jsonResult($values = array()) {
        $result = new Dcmp_Component_Result_Json($this->getComponent());
        $result->addData($values);
        return $result;
    }
    
    protected function templateResult($values = array(), $path = NULL){
    	$result = new Dcmp_Component_Result_Template($this);
        if (!empty($values) && is_array($values)) {
            $result->addData($values);
        }
        if(is_null($path)){
        	$path = implode(DS, array('component',
        							  $this->getRouter()->getComponent(),
        							  $this->getRouter()->getController(),
        							  $this->getRouter()->getAction().'.phtml'));
        }
        $result->setPath($path);
        return $result;
    }
    
    protected function errorResult($message = ''){
    	$result = new Dcmp_Component_Result_Error($this);
    	$result->setMessage($message);
    	return $result;
    }

    protected function callMethod($methodName, $fillQueryParams = TRUE) {
        $methodParams = array();
        if ($fillQueryParams) {
            $reqParams = $this->getRequest()->getAllParameters();
            $refMethod = new ReflectionMethod(get_class($this), $methodName);
            if ($refMethod->getNumberOfParameters() > 0) {
                foreach ($refMethod->getParameters() as $parameter) {
                    if (array_key_exists($parameter->getName(), $reqParams)) {
                        $rv = $this->getRequest()->getParameter($parameter->getName(), NULL);
                        if (is_null($rv)) {
                            if (!$parameter->isOptional()) {
                                throw new Exception('invalid parameter');
                            }
                            $rv = $parameter->getDefaultValue();
                        }
                    }
//                    elseif (strpos($parameter->getName(), '_')) {
//                        $pn = explode('_', $parameter->getName());
//                        $rv = $this->getRequest()->getParameter($pn[1], NULL);
//                        $pass = TRUE;
//                        switch ($pn[0]) {
//                            case 'integer':
//                                $pass = Kd_Validate::isInteger($rv);
//                                break;
//                            case 'number':
//                                $pass = Kd_Validate::isNumeric($rv);
//                                break;
//                            case 'date':
//                                $pass = Kd_Validate::testDate($rv);
//                                break;
//                            case 'requried':
//                                $pass = Kd_Validate::isNotEmpty($rv);
//                                break;
//                            default:
//                                $pass = TRUE;
//                                break;
//                        }
//                        if (!$pass) {
//                            if (!$parameter->isOptional()) {
//                                throw new Exception('invalid parameter');
//                            }
//                            $rv = $parameter->getDefaultValue();
//                        }
//                    }
					else {
                        if (!$parameter->isOptional()) {
                            throw new Exception('invalid parameter');
                        }
                        $rv = $parameter->getDefaultValue();
                    }
                    $methodParams[] = $rv;
                }
            }
        }
        return call_user_func_array(array($this, $methodName), $methodParams);
    }

    protected function getActionMethods($action) {
        $requestMethod = ucfirst($this->getRequest()->getMethod());
        return array(
            $action . $requestMethod . 'Action',
            $action . 'Action'
        );
    }

    public function execute($action = NULL) {
        if (is_null($action)) {
            $action = $this->getRouter()->getAction();
        }
        $action = Kd_Util_String::lowerFirstChar(str_replace(' ', '', ucwords(str_replace('-', ' ', $action))));
        $methods = $this->getActionMethods($action);
        foreach ($methods as $method) {
            if (method_exists($this, $method)) {
                return $this->callMethod($method);
            }
        }
    }

}